﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "SpriteFrameCache.h"
#include "../external/Tinyxml2/tinyxml2.h"
#include "../utility/StringUtility.h"
#include "../render/Texture2D.h"
#include "../node/SpriteFrame.h"
#include "../base/Debuger.h"

using namespace tinyxml2;

namespace SkyEngine2d
{
	
	struct SpriteFrameCache::Imp
	{
		std::unique_ptr<tinyxml2::XMLDocument> m_xmlDoc;
	
		Imp() {}
		~Imp() {}
	
	};
	
	SpriteFrameCache::SpriteFrameCache()
		:m_imp(nullptr)
	{
		m_imp = std::make_unique<Imp>();
		m_imp->m_xmlDoc = std::make_unique<tinyxml2::XMLDocument>();
	}
	
	SpriteFrameCache::~SpriteFrameCache()
	{
	
	}
	
	bool SpriteFrameCache::addSpriteFramesWithImagePack(const std::wstring& imagepack_file_name, const std::wstring& image_path)
	{
		m_imp->m_xmlDoc->Clear();
	
		XMLError err = m_imp->m_xmlDoc->LoadFile(StringUtility::wcharToChar(imagepack_file_name).c_str());
		if (err != XML_SUCCESS)
		{
			return false;
		}
	
		auto xml_p = m_imp->m_xmlDoc.get();
		XMLElement* root = xml_p->RootElement();
	
		//创建纹理
		Texture2DSharedPtr texture = Texture2D::create(image_path);
		if (!texture)
		{
			return false;
		}
		Size tex_size = texture->getContentSize();
		//创建精灵帧
		XMLElement* element = root->FirstChildElement();
		while (element)
		{
			std::wstring name = StringUtility::charToWchar(element->FindAttribute("n")->Value());
			int pos = name.find(L".");
			name = name.substr(0, pos);
			float x = element->FindAttribute("x")->FloatValue();
			float y = element->FindAttribute("y")->FloatValue();
			float w = element->FindAttribute("w")->FloatValue();
			float h = element->FindAttribute("h")->FloatValue();
	
			auto sf = SpriteFrame::createFromTexture(texture, Rect(x, tex_size.height - y - h, w, h));
	
			DebugerAssert(sf, "精灵帧为空，可能是加载精灵错误");
	
			m_name2SpriteFramePtr.emplace(std::move(name), std::move(sf));
	
			element = element->NextSiblingElement();
		}
	
		return true;
	}
	
	bool SpriteFrameCache::addSpriteFrame(const SpriteFrameSharedPtr & sprite_frame, const std::wstring & name)
	{
		auto f = m_name2SpriteFramePtr.find(name);
		if (f!=m_name2SpriteFramePtr.end())
		{
			return false;
		}
		m_name2SpriteFramePtr.emplace(name, sprite_frame);
		return true;
	}
	
	SpriteFrameSharedPtr SpriteFrameCache::getSpriteFrame(const std::wstring & name)
	{
		auto f = m_name2SpriteFramePtr.find(name);
		if (f!=m_name2SpriteFramePtr.end())
		{
			return f->second;
		}
		return nullptr;
	}
	
	void SpriteFrameCache::removeSpriteFrame(const std::wstring & name)
	{
		m_name2SpriteFramePtr.erase(name);
	}
	
	void SpriteFrameCache::removeAllSpriteFrame()
	{
		m_name2SpriteFramePtr.clear();
	}
	
}
